class ScreenSnipper {
    constructor() {
        this.canvas = document.createElement('canvas')
        this.canvas.id = 'snipCanvas'
        this.ctx = this.canvas.getContext('2d')
        document.body.appendChild(this.canvas)

        this.toolbar = this.createToolbar()

        this.vedio = null
        this.stream = null
        this.isSelecting = false
        this.isDragging = false
        this.startX = this.startY = this.endX = this.endY = undefined;
        this.dragOffsetX = this.dragOffsetY = 0; // 拖动偏移量
        this.animationId = null
        this.initEvents()
    }

    initEvents() {
        this.canvas.onmousedown = e => this.handleMouseDown(e)
        this.canvas.onmousemove = e => this.handleMouseMove(e)
        this.canvas.onmouseup = e => this.handleMouseUp(e)
        this.canvas.oncontextmenu = e => e.preventDefault()

        window.addEventListener('keydown', e => this.handleKeyDown(e))
        window.addEventListener('beforeunload', () => { this.stopCapture() })
    }

    handleMouseDown(e) {
        const rectX = Math.min(this.startX || 0, this.endX || 0);
        const rectY = Math.min(this.startY || 0, this.endY || 0);
        const rectW = Math.abs((this.endX || 0) - (this.startX || 0));
        const rectH = Math.abs((this.endY || 0) - (this.startY || 0));

        console.log(e.button)
        if (e.button === 0) {
            this.isSelecting = true
            this.startX = e.offsetX;
            this.startY = e.offsetY;
            this.endX = this.startX;
            this.endY = this.startY;
            this.toolbar.style.display = "none";
        }

        if (e.button === 2 && rectH > 5 && rectW > 5) {
            console.log('右键移动')
            if (e.offsetX >= rectX && e.offsetX <= rectX + rectW &&
                e.offsetY >= rectY && e.offsetY <= rectY + rectH) {
                    this.isDragging = true
                     this.dragOffsetX = e.offsetX - rectX;
                    this.dragOffsetY = e.offsetY - rectY;
                    this.toolbar.style.display = "none";
                    return;
            }
        }
    }

    handleMouseMove (e) {
        if (this.isSelecting) {
            this.endX = e.offsetX
            this.endY = e.offsetY
        } else if (this.isDragging) {
            // 拖动选区位置
            const rectW = Math.abs(this.endX - this.startX);
            const rectH = Math.abs(this.endY - this.startY);
            this.startX = e.offsetX - this.dragOffsetX;
            this.startY = e.offsetY - this.dragOffsetY;
            this.endX = this.startX + rectW;
            this.endY = this.startY + rectH;
        }
    }

    handleMouseUp() {
        this.isSelecting = false;
        this.isDragging = false
    }

    createToolbar() {
        const toolbar = document.createElement('div')
        toolbar.style.cssText = `
            position: absolute;
            display: none;
            background: rgba(0,0,0,0.75);
            padding: 4px 8px;
            border-radius: 4px;
            gap: 6px;
            z-index: 9999;
        `;

        const saveBtn = document.createElement('div')
        saveBtn.textContent = '保存'
        saveBtn.style.cssText = `
            background: #4CAF50;
            color: white;
            border: none;
            padding: 4px 8px;
            border-radius: 4px;
            cursor: pointer;
        `;
        saveBtn.onclick = () => this.captureSelection();

        const cancelBtn = document.createElement('div')
        cancelBtn.textContent = '取消'
        cancelBtn.style.cssText = `
            background: #f44336;
            color: white;
            border: none;
            padding: 4px 8px;
            border-radius: 4px;
            cursor: pointer;
        `;

        toolbar.appendChild(saveBtn)
        toolbar.appendChild(cancelBtn)

        document.body.appendChild(toolbar)
        return toolbar;
    }

    async start () {
        try {
            this.stream = await navigator.mediaDevices.getDisplayMedia({ video: true })
            this.video = document.createElement('video')
            this.video.srcObject = this.stream
            await this.video.play()

            this.canvas.width = this.video.videoWidth
            this.canvas.height = this.video.videoHeight
            this.canvas.style.cssText = `
                position: fixed;
                top: 0;
                left: 0;
                z-index: 9998;
                cursor: crosshair;
            `;
             // 启动绘制循环
            this.startDrawing();
        } catch (error) {
            console.error("Screen capture failed:", error);
        }
    }
    startDrawing() {
        this.drawVideoToCanvas();
    }

    drawVideoToCanvas() {
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
        this.ctx.drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height)
        if ((this.isSelecting || this.isDragging || this.startX !== undefined) && this.startX !== undefined) {
            const x = Math.min(this.startX, this.endX);
            const y = Math.min(this.startY, this.endY);
            const w = Math.abs(this.endX - this.startX);
            const h = Math.abs(this.endY - this.startY);
            this.ctx.fillStyle = "rgba(0, 0, 0, 0.4)"
            this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height)
            this.ctx.drawImage(this.video, x, y, w, h, x, y, w, h)

            this.ctx.strokeStyle = '#00f'
            this.ctx.lineWidth = 2
            this.ctx.strokeRect(x, y, w, h)
            if (this.isSelecting && !this.isDragging && w > 5 && h > 5) {
                this.toolbar.style.left = (x + w + 10) + 'px'
                this.toolbar.style.top = (y + h + 10) + 'px'
                this.toolbar.style.display = 'flex'
            }
        }
        this.animationId = requestAnimationFrame(() => this.drawVideoToCanvas())
    }
    captureSelection() {
        const x = Math.min(this.startX, this.endX);
        const y = Math.min(this.startY, this.endY);
        const w = Math.abs(this.endX - this.startX);
        const h = Math.abs(this.endY - this.startY);

        if (w < 5 || h < 5) return; // 防止选区太小
        const tempCanvas = document.createElement('canvas')
        tempCanvas.width = w
        tempCanvas.height = h
        const tempctx = tempCanvas.getContext('2d')
        tempctx.drawImage(this.canvas, x, y, w, h, 0, 0, w, h)

        const dataUrl = tempCanvas.toDataURL('image/png')
        this.downloadImage(dataUrl, "screenshot_" + new Date().getTime() + ".png");
        this.stopCapture();
    }
    downloadImage(url, name) {
        const a = document.createElement('a')
        a.download = name
        a.href = url
        document.body.appendChild(a)
        a.click()
        document.body.removeChild(a)
    }
    handleKeyDown(e) {
        const step = e.shiftKey ? 10 : 1
        // 微调选区
        if (this.startX !== undefined && this.endX !== undefined) {
            const rectW = Math.abs(this.endX - this.startX);
            const rectH = Math.abs(this.endY - this.startY);
            if (e.key === 'ArrowUp') {
                this.startY = Math.max(0, this.startY - step)
                this.endY = this.startY + rectH
            }
            if (e.key === 'ArrowDown') {
                this.startY = Math.min(this.canvas.height- rectH, this.startY + step)
                this.endY = this.startY + rectH
            }

            if (e.key === 'ArrowLeft') {
                this.startX = Math.max(0, this.startX - step)
                this.endX = this.startX + rectW
            }

            if (e.key === 'ArrowRight') {
                this.startX = Math.min(this.canvas.width - rectW, this.startX + step);
                this.endX = this.startX + rectW;
            } 
        }


        // ESC 取消截图
        if (e.key === 'Escape') {
            this.stopCapture()
        } 
        // Enter 保存
        if (e.key === 'Enter') {
             if (!this.isSelecting && this.startX !== undefined && this.endX !== undefined) {
                this.captureSelection();
            }
        }
    }
    stopCapture() {
        cancelAnimationFrame(this.animationId)
        if (this.stream) {
            this.stream.getTracks().forEach(track => {
                track.stop()
            })
            this.canvas.width = 0
            this.canvas.height = 0
            this.toolbar.style.display = 'none'
            this.startX = this.startY = this.endX = this.endY = undefined;
        }
    }
}